home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Bzr-Read.c - Bezier curves handling routines - read from file. *
- *******************************************************************************
- * Written by Gershon Elber, Mar. 90. *
- ******************************************************************************/
-
- #include <ctype.h>
- #include <stdio.h>
- #include <string.h>
- #include "cagd_loc.h"
- #include "irit_soc.h"
-
- #define UNGET_STACK_SIZE 3
- #define ZERO_NUM_EPSILON 1e-15
-
- int _CagdGlblLineCount = 1; /* Used to locate errors in input file. */
-
- static int
- GlblUnGetChar = 0,
- GlblReadSocket = FALSE, /* If TRUE - read from socket. */
- GlblTknStackSize = 0; /* Used by parser, to unget token. */
- static char
- GlblStringToken[UNGET_STACK_SIZE][LINE_LEN], /* Save unget tokens.*/
- CagdFloatFormat[LINE_LEN] = /* Floating point printing format. */
- #ifdef DOUBLE
- "%-8.6lg";
- #else
- "%-8.6g";
- #endif /* DOUBLE */
-
- static void InputUnGetC(char c);
- static char InputGetC(FILE *f);
- static int InputEOF(FILE *f);
- static void GetStringToken(FILE *f, char *StringToken);
-
- /*****************************************************************************
- * Routine to read from input file f the following [ATTR ...] [ATTR ...]. *
- * Note the '[' was allready read. *
- * Current supported attributes: None. *
- * Returns NULL if O.k., otherwise string describing the error. *
- *****************************************************************************/
- char *_CagdGetCurveAttributes(FILE *f)
- {
- TokenNumType i;
- char StringToken[LINE_LEN];
-
- do {
- switch (_CagdGetToken(f, StringToken)) {
- default:
- while ((i = _CagdGetToken(f, StringToken)) !=
- TOKEN_CLOSE_PAREN &&
- i != TOKEN_EOF);
- if (i == TOKEN_EOF)
- return "EOF detected in middle of attribute.";
- break;
- }
- }
- while (_CagdGetToken(f, StringToken) == TOKEN_OPEN_PAREN);
-
- _CagdUnGetToken(StringToken);
-
- return NULL;
- }
-
- /*****************************************************************************
- * Routine to read from input file f the following [ATTR ...] [ATTR ...]. *
- * Note the '[' was allready read. *
- * Current supported attributes: None. *
- * Returns NULL if O.k., otherwise string describing the error. *
- *****************************************************************************/
- char *_CagdGetSurfaceAttributes(FILE *f)
- {
- TokenNumType i;
- char StringToken[LINE_LEN];
-
- do {
- switch (_CagdGetToken(f, StringToken)) {
- default:
- while ((i = _CagdGetToken(f, StringToken)) !=
- TOKEN_CLOSE_PAREN &&
- i != TOKEN_EOF);
- if (i == TOKEN_EOF)
- return "EOF detected in middle of attribute.";
- break;
- }
- }
- while (_CagdGetToken(f, StringToken) == TOKEN_OPEN_PAREN);
-
- _CagdUnGetToken(StringToken);
-
- return NULL;
- }
-
- /*****************************************************************************
- * Routine to unget a single character from input stream. *
- *****************************************************************************/
- static void InputUnGetC(char c)
- {
- GlblUnGetChar = c;
- }
-
- /*****************************************************************************
- * Routine to get a single character from input stream. *
- * If input returns EOF wait until new inputs arrive (can happen if reading *
- * from a non io blocked socket). *
- *****************************************************************************/
- static char InputGetC(FILE *f)
- {
- char c;
-
- do {
- if (GlblUnGetChar) {
- c = GlblUnGetChar;
-
- GlblUnGetChar = 0;
- }
- else if (GlblReadSocket)
- c = SocClientReadCharNonBlock();
- else
- c = getc(f);
-
- if (c == (char) EOF)
- IritSleep(10);
- }
- while (c == (char) EOF);
-
- return c;
- }
-
- /*****************************************************************************
- * Routine to test for EOF condition in input stream. *
- *****************************************************************************/
- static int InputEOF(FILE *f)
- {
- if (GlblReadSocket)
- return FALSE;
- else
- return feof(f);
- }
-
- /******************************************************************************
- * Routine to unget one token (on stack of UNGET_STACK_SIZE levels!) *
- ******************************************************************************/
- void _CagdUnGetToken(char *StringToken)
- {
- if (GlblTknStackSize >= UNGET_STACK_SIZE)
- FATAL_ERROR(CAGD_ERR_PARSER_STACK_OV);
-
- strcpy(GlblStringToken[GlblTknStackSize++], StringToken);
- }
-
- /******************************************************************************
- * Routine to get the next token out of the input file f. *
- * Returns the next token found, as StringToken. *
- * Note: StringToken must be allocated before calling this routine! *
- ******************************************************************************/
- static void GetStringToken(FILE *f, char *StringToken)
- {
- int Len;
- char *LocalStringToken,
- c = 0;
-
- if (GlblTknStackSize) { /* Get first the unget token. */
- strcpy(StringToken, GlblStringToken[--GlblTknStackSize]);
- return;
- }
-
- /* skip white spaces and comments: */
- while (!InputEOF(f) &&
- ((c = InputGetC(f)) == ' ' || c == '\t' || c == '\n' || c == '#')) {
- /* Skip a comment if encounter one. */
- if (c == '#')
- while (!InputEOF(f) && c != '\n')
- c = InputGetC(f);
- if (c == '\n')
- _CagdGlblLineCount++; /* Count the lines. */
- }
-
- LocalStringToken = StringToken;
- if (c == '[') /* Its a token by itself so return it. */
- *LocalStringToken++ = c; /* Copy the token into string. */
- else {
- if (!InputEOF(f))
- do
- *LocalStringToken++ = c; /* Copy the token into string. */
- while ((!InputEOF(f)) &&
- ((c = InputGetC(f)) != ' ') && (c != '\t') && (c != '\n'));
- if (c == '\n')
- InputUnGetC(c); /* Save it to be counted next time. */
- }
- *LocalStringToken = 0; /* Put eos. */
-
- /* The following handles the spacial case were we have XXXX] - we must */
- /* split it into two token XXXX and ], UnGetToken(']') and return XXXX: */
- if ((StringToken[Len = strlen(StringToken)-1] == ']') && (Len > 0)) {
- /* Return CloseParen */
- _CagdUnGetToken(&StringToken[Len]); /* Save next token. */
- StringToken[Len] = 0; /* Set end of string on "]". */
- }
- }
-
- /******************************************************************************
- * Routine to get the next token out of the input file f as token number. *
- * Returns the next token number found, with numeric result in NumericToken *
- * if TokenType is TOKEN_NUMBER. *
- * Note: StringToken must be allocated before calling this routine! *
- ******************************************************************************/
- TokenNumType _CagdGetToken(FILE *f, char *StringToken)
- {
- GetStringToken(f, StringToken);
-
- if (InputEOF(f))
- return TOKEN_EOF;
-
- if (!strcmp(StringToken, "["))
- return TOKEN_OPEN_PAREN;
- if (!strcmp(StringToken, "]"))
- return TOKEN_CLOSE_PAREN;
-
- if (!strcmp(StringToken, "BEZIER"))
- return TOKEN_BEZIER;
- if (!strcmp(StringToken, "BSPLINE"))
- return TOKEN_BSPLINE;
- if (!strcmp(StringToken, "POWER"))
- return TOKEN_POWER;
-
- if (!strcmp(StringToken, "CURVE"))
- return TOKEN_CURVE;
- if (!strcmp(StringToken, "SURFACE"))
- return TOKEN_SURFACE;
-
- if (!strcmp(StringToken, "PTYPE"))
- return TOKEN_PTYPE;
- if (!strcmp(StringToken, "NUMPTS"))
- return TOKEN_NUM_PTS;
- if (!strcmp(StringToken, "ORDER"))
- return TOKEN_ORDER;
-
- if (!strcmp(StringToken, "KV"))
- return TOKEN_KV;
-
- return TOKEN_OTHER; /* Must be number or name. */
- }
-
- /*****************************************************************************
- * Routine to request reading from a socket (if non zero) instead of a file. *
- *****************************************************************************/
- void CagdReadSocket(int ReadSocket)
- {
- GlblReadSocket = ReadSocket;
- }
-
- /*****************************************************************************
- * Set the floating point numbers printing format. *
- *****************************************************************************/
- void CagdSetFloatFormat(char *FloatFormat)
- {
- strncpy(CagdFloatFormat, FloatFormat, LINE_LEN - 1);
- }
-
- /*****************************************************************************
- * Convert a real number into a string. *
- *****************************************************************************/
- char *_CagdReal2Str(CagdRType R)
- {
- static char Buffer[LINE_LEN];
- int j;
-
- if (ABS(R) < ZERO_NUM_EPSILON)
- R = 0.0;
-
- sprintf(Buffer, CagdFloatFormat, R);
-
- for (j = strlen(Buffer) - 1; Buffer[j] == ' ' && j > 0; j--);
- if (strchr(Buffer, '.') != NULL)
- for (; Buffer[j] == '0' && j > 0; j--);
- Buffer[j+1] = 0;
-
- return Buffer;
- }
-